package com.runfast.pay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipayHashMap;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.RequestParametersHolder;
import com.alipay.api.internal.util.json.JSONWriter;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.runfast.pay.alipay.AlipayConfig;
import com.runfast.pay.service.AlipayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: lijin
 * @date: 2018年03月30日
 */

@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {

    private final static String serverUrl = "https://openapi.alipay.com/gateway.do";

    private AlipayClient alipayClient = new DefaultAlipayClient(serverUrl,
            AlipayConfig.aliPay_AppID,
            AlipayConfig.private_key,
            "json", "utf-8",
            AlipayConfig.ali_public_key,
            AlipayConfig.sign_type
    );

    @Override
    public Map<String, String> prepay(String orderNo, int amountPayable, String subject, String productCode, String timeoutExpress, String notifyUrl)  {
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayHashMap protocalMustParams = new AlipayHashMap();
        protocalMustParams.put(AlipayConstants.METHOD, request.getApiMethodName());
        protocalMustParams.put(AlipayConstants.VERSION, request.getApiVersion());
        protocalMustParams.put(AlipayConstants.APP_ID, AlipayConfig.aliPay_AppID);
        protocalMustParams.put(AlipayConstants.SIGN_TYPE, AlipayConfig.sign_type);
        protocalMustParams.put(AlipayConstants.NOTIFY_URL,  notifyUrl);
        protocalMustParams.put(AlipayConstants.CHARSET, AlipayConfig.input_charset);

        Long timestamp = System.currentTimeMillis();
        DateFormat df = new SimpleDateFormat(AlipayConstants.DATE_TIME_FORMAT);
        df.setTimeZone(TimeZone.getTimeZone(AlipayConstants.DATE_TIMEZONE));
        protocalMustParams.put(AlipayConstants.TIMESTAMP, df.format(new Date(timestamp)));

        AlipayTradeAppPayModel appPayModel = new AlipayTradeAppPayModel();

        appPayModel.setSubject(subject);
        appPayModel.setOutTradeNo(orderNo);
        appPayModel.setTotalAmount(amountPayable/100f + "");
        appPayModel.setProductCode(productCode);
        appPayModel.setTimeoutExpress(timeoutExpress);
//        appPayModel.setSellerId(AlipayConfig.partner);

        JSONWriter jsonWriter = new JSONWriter();

            protocalMustParams.put(AlipayConstants.BIZ_CONTENT_KEY, jsonWriter.write(appPayModel,true));


        RequestParametersHolder requestHolder = new RequestParametersHolder();
        requestHolder.setProtocalMustParams(protocalMustParams);
        String signContent = AlipaySignature.getSignatureContent(requestHolder);

        String rsaSign = "";
        try {
            rsaSign = AlipaySignature.rsaSign(signContent, AlipayConfig.private_key, AlipayConfig.input_charset, AlipayConfig.sign_type);
            protocalMustParams.put("sign",rsaSign);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }


        return protocalMustParams;
    }

    @Override
    public AlipayTradeQueryResponse orderQuery(String orderNo) {
        Validate.notBlank(orderNo, "orderNo 不能为空");


        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel();
        queryModel.setOutTradeNo(orderNo);
        request.setBizModel(queryModel);

        try {
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            return response;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }


    }

    @Override
    public AlipayTradeFastpayRefundQueryResponse refundQuery(String refundNo) {
        Validate.notBlank(refundNo, "refundNo 不能为空");

        AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();

        AlipayTradeFastpayRefundQueryModel refundQueryModel = new AlipayTradeFastpayRefundQueryModel();
        refundQueryModel.setOutRequestNo(refundNo);
        request.setBizModel(refundQueryModel);

        try {
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
            return response;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }


    }


    @Override
    public AlipayTradeRefundResponse applyRefund(String orderNo, String refundNo, Integer refundAmount) {
        Validate.notBlank(orderNo, "orderNo 不能为空");
        Validate.notBlank(refundNo, "refundNo 不能为空");
        Validate.notNull(refundAmount, "refundAmount 不能为null");

        AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();

        AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();
        refundModel.setOutTradeNo(orderNo);
        refundModel.setOutRequestNo(refundNo);
        refundModel.setRefundAmount(String.valueOf(refundAmount / 100f));

        refundRequest.setBizModel(refundModel);
        try {
            AlipayTradeRefundResponse response = alipayClient.execute(refundRequest);
            return response;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public AlipayTradeCloseResponse closeOrder(String orderNo) {
        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();

        AlipayTradeCloseModel closeModel = new AlipayTradeCloseModel();
        closeModel.setOutTradeNo(orderNo);

        request.setBizModel(closeModel);

        try {
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            return response;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }


    @Override
    public AlipayTradeAppPayResponse realPay(String orderNo, int amountPayable, String subject, String productCode, String timeoutExpress, String notifyUrl) {
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();


//        Map<String, String> prepay = prepay(orderNo, amountPayable, subject, productCode, timeoutExpress, notifyUrl);
//        request.setApiVersion(prepay.get(AlipayConstants.VERSION));
//        request.setNotifyUrl(prepay.get(AlipayConstants.NOTIFY_URL));


        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo(orderNo);
        model.setTotalAmount(amountPayable/100f+"");
        model.setSubject(subject);
        model.setProductCode(productCode);
        model.setTimeoutExpress(timeoutExpress);


        request.setNotifyUrl(notifyUrl);
        request.setBizModel(model);

        try {
            AlipayTradeAppPayResponse response = alipayClient.execute(request);
            return response;
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
}
